package org.example.ag_notes.security;

import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import org.example.ag_notes.config.JwtProperties;
import org.springframework.stereotype.Component;
import io.jsonwebtoken.MissingClaimException;
import javax.crypto.SecretKey;
import java.util.Date;

@Component
public class JwtTokenProvider {
    private final JwtProperties jwtProperties;
    private final SecretKey secretKey;



    public JwtTokenProvider(JwtProperties jwtProperties) {
        this.jwtProperties = jwtProperties;
        // 使用Base64解码密钥字符串
        this.secretKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtProperties.getSecret()));
    }

    public String generateAccessToken(String username) {
        return generateToken(username, jwtProperties.getAccessTokenExpirationMs());
    }

    public String generateRefreshToken(String username) {
        return generateToken(username, jwtProperties.getRefreshTokenExpirationMs());
    }

    private String generateToken(String username, long expirationMs) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + expirationMs);

        return Jwts.builder()
                .subject(username)
                .issuedAt(now)
                .expiration(expiryDate)
                .signWith(secretKey, Jwts.SIG.HS512)
                .compact();
    }

    public String getUsernameFromToken(String token) {
        return Jwts.parser()
                .verifyWith(secretKey)
                .build()
                .parseSignedClaims(token)
                .getPayload()
                .getSubject();
    }

    public boolean validateToken(String token) {
        try {
            Jwts.parser()
                    .verifyWith(secretKey)
                    .build()
                    .parseSignedClaims(token);
            return true;
        } catch (JwtException | IllegalArgumentException ex) {
            // 捕获所有JWT相关异常
            return false;
        }
    }

    /**
     * 从Token中解析用户ID
     * @param token JWT Token
     * @return 用户ID
     * @throws JwtException 如果Token无效或未包含用户ID
     */
    public Integer getUserIdFromToken(String token) throws JwtException {
        try {
            // 1. 解析Token获取Header和Claims
            Jws<Claims> jws = Jwts.parser()
                    .verifyWith(secretKey)
                    .build()
                    .parseSignedClaims(token);

            Header header = jws.getHeader();
            Claims claims = jws.getPayload();

            // 2. 获取用户ID Claim
            Integer userId = claims.get("userId", Integer.class);

            // 3. 处理缺失Claim的情况
            if (userId == null) {
                throw new MissingClaimException(
                        header,          // JWT Header
                        claims,         // JWT Claims
                        "userId",       // 缺失的Claim名称
                        null,           // 期望的Claim值（因缺失所以为null）
                        "Token中缺少用户ID声明" // 错误消息
                );
            }

            return userId;
        } catch (JwtException e) {
            throw new JwtException("Token解析失败: " + e.getMessage(), e);
        }
    }
}